package com.vietnam.power.dao.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.vietnam.power.dao.ArticleDao;
import com.vietnam.power.domain.ArticleSearchCriteria;
import com.vietnam.power.persitence.Article;
import com.vietnam.power.persitence.ArticleGroup;

@Repository
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public class ArticleDaoImpl extends GenericDaoImpl implements ArticleDao {

	@Transactional(readOnly = true)
	public Article getArticleById(int id) {
		return findById(Article.class, id);
	}

	@SuppressWarnings("unchecked")
	public List<Article> getArticleListByCriteria(ArticleSearchCriteria psc, int page, int max) {
		Criteria crt = getSessionFactory().getCurrentSession().createCriteria(Article.class);
		if (psc != null && psc.getArticleGroupName() != null) {
			crt.createAlias("articleGroup", "articleGroup");
			crt.add(Restrictions.eq("articleGroup.name", psc.getArticleGroupName()));
		}

		if (psc != null && psc.getCurrentArticleId() != null) {
			crt.add(Restrictions.ne("id", psc.getCurrentArticleId()));
		}
		crt.addOrder(Order.desc("createdDate"));
		crt.setFirstResult((page - 1) * max);
		crt.setMaxResults(max);

		return crt.list();
	}

	public int totalArticles(ArticleSearchCriteria psc) {
		Criteria crt = getSessionFactory().getCurrentSession().createCriteria(Article.class);
		if (psc != null && psc.getArticleGroupName() != null) {
			crt.createAlias("articleGroup", "articleGroup");
			crt.add(Restrictions.eq("articleGroup.name", psc.getArticleGroupName()));
		}
		if (psc != null && psc.getCurrentArticleId() != null) {
			crt.add(Restrictions.ne("id", psc.getCurrentArticleId()));
		}
		crt.setProjection(Projections.rowCount());

		return ((Long) crt.uniqueResult()).intValue();
	}

	public void createArticleGroup(ArticleGroup ag) {
		persist(ag);
	}

	public void updateArticleGroup(ArticleGroup ag) {
		merge(ag);
	}

	public ArticleGroup getArticleGroup(int id) {
		return findById(ArticleGroup.class, id);
	}

	public void deleteArticleGroup(ArticleGroup ag) {
		delete(ag);
	}

	public void createArticle(Article a) {
		save(a);
	}

	public void updateArticle(Article a) {
		merge(a);
	}

	public void deleteArticle(Article a) {
		delete(a);
	}

	@SuppressWarnings("unchecked")
	public List<Article> searchArticle(ArticleSearchCriteria psc) {
		Criteria crt = getSessionFactory().getCurrentSession().createCriteria(Article.class);
		if (psc.getArticelGroupId() != null) {
			crt.createAlias("articleGroup", "articleGroup");
			crt.add(Restrictions.eq("articleGroup.id", psc.getArticelGroupId()));
		}

		if (psc != null && psc.getCurrentArticleId() != null) {
			crt.add(Restrictions.ne("id", psc.getCurrentArticleId()));
		}

		if (StringUtils.isNotBlank(psc.getKeyword())) {
			crt.add(Restrictions.ilike("keyword", psc.getKeyword(), MatchMode.ANYWHERE));
		}

		if (StringUtils.isNotBlank(psc.getName())) {
			crt.add(Restrictions.ilike("name", psc.getName(), MatchMode.ANYWHERE));
		}

		crt.addOrder(Order.desc("createdDate"));

		return crt.list();
	}

	public List<ArticleGroup> getArticleGroupList() {
		return findAll(ArticleGroup.class);
	}

	public long countArticleNumberInGroup(int groupId) {
		Criteria crt = getSessionFactory().getCurrentSession().createCriteria(Article.class);
		crt.createAlias("articleGroup", "articleGroup");
		crt.add(Restrictions.eq("articleGroup.id", groupId));

		return (Long) crt.setProjection(Projections.rowCount()).uniqueResult();
	}
}
